package main

import (
	"fmt"
	"time"
)

/*
future 模式
	编程中经常遇到一个流程中需要调用多个子调用的情况，这些子调用相互之间没有依赖，如果串行地调用，则会耗时很长，此时可以使用Go并发编程中的future模式

	基本原理：
		1.使用 chan 作为函数参数
		2.启动 goroutine 调用函数
		3.通过 chan 调用参数
		4.做其他可以并行处理的事情
		5.通过 chan 异步获取结果

	优点：将函数的同步调用转换为异步调用，适用于一个交易需要多个子调用且这些子调用没有依赖的场景
*/

// 一个查询结构体
// 这里的 sql 和 result 是一个简单的抽象，具体的应用可能是更复杂的数据结构
type query struct {
	sql chan string //参数 channel

	result chan string //结果 channel
}

// 执行 Query
func exeQuery(q query) {
	//启动协程
	go func() {
		//获取输入
		sql := <-q.sql

		//访问数据库

		//输出结果通道
		q.result <- "result from " + sql
	}()
}

func main() {
	//初始化Query
	q := query{make(chan string, 1), make(chan string, 1)}

	//执行Query，注意执行的时候无须准备参数
	go exeQuery(q)

	//发送参数
	q.sql <- "select * from table"

	//做其他事情，通过 sleep 描述
	time.Sleep(1 * time.Second)

	//获取结果
	fmt.Println(<-q.result)
}
